/*=====================================================================================================================
                    Copyright(c) 2009 Geometric PLM Software Corp. All rights reserved.
                             Unpublished - All rights reserved
=======================================================================================================================
File description:
    Filename: tc_log.c
    Module  : (geometric) itk module.

        This file manages the operations of the log file.

=======================================================================================================================
Date               Name              Description of Change
10-Sep-2009        Penn,Xie          Initialize creation
$HISTORY$
=====================================================================================================================*/
#ifndef _cplusplus
#define _CRT_SECURE_NO_DEPRECATE
#endif

#include <tc/emh.h>

#ifdef BUILD_IMAN
#include <iman_string.h>
#include <iman_util.h>

#define GTC_write_syslog            IMAN_write_syslog

#else
#include <fclasses\tc_string.h>
#include <tc\tc_util.h>

#define GTC_write_syslog            TC_write_syslog
#endif

#include "file_utils.h"
#include "tc_log.h"
#include "string_utils.h"
#include "tc_utils.h"



#ifdef SYSLOG_ON
#define CONSOLE_SYS_PRINT       1
#define CONSOLE_PRINT           1
#else
#define CONSOLE_SYS_PRINT       0
#define CONSOLE_PRINT           0
#endif


/*
 * Define the global pointer for log
*/
DEBUG_LOG_t GLOG_instance = {NULL, false};


int GLOG_def_user_open( const char *funcName, const char *welcome, FILE **file )
{
    int ifail = ITK_ok;
    char *userID = NULL;
    ifail = POM_get_user_id(&userID);
    if(ifail == ITK_ok)
    {
        ifail = GLOG_open(funcName, userID, welcome, file);
        MEM_free(userID);
    }
    return ifail;
}

int GLOG_open( const char *funcName, const char *userId, const char *welcome, FILE **file )
{
    int ifail = ITK_ok;
    char *logPath = NULL;

    ifail = GLOG_open_ex( funcName, userId, welcome, &logPath, file );
    MEM_free( logPath );

    return ifail;
}

int GLOG_open_ex( const char *funcName, const char *userId, const char *welcome, char **logPath, FILE **file )
{
    return FILE_open( funcName, userId, ".log", welcome, logPath, file );
}

void GLOG_close( FILE **f )
{
    FILE_close( f );
}


void GLOG_println( FILE* f, int level, logical debug, const char *text )
{
    GLOG_print(f, level, debug, text);
    GLOG_print(f, level, debug, "\n");
}

void GLOG_print( FILE* f, int level, logical debug, const char *text )
{
    if ( level == EMH_severity_error || level == EMH_severity_warning || (level == EMH_severity_information && debug ) )
    {
        if (f != NULL)
        {
            fprintf( f, text );
        }
        if ( CONSOLE_PRINT )
        {
            if ( CONSOLE_SYS_PRINT )
                GTC_write_syslog( "%s", text );
            printf( "%s", text );
        }
    }
	fflush(f);
}

void GLOG_sprint_ex(FILE* f, int level, logical debug, const char *format, va_list arg_ptr)
{
    unsigned int buffSize = 256;
    char *buff = NULL;

    if(format != NULL)
    {
        int sprnSize = -1;
        do
        {
            buffSize *= 2;
            MEM_free(buff);
            buff = NULL;
            buff = MEM_alloc(buffSize + 1);
            sprnSize = vsnprintf(buff, buffSize, format, arg_ptr);
            buff[buffSize] = '\0';
        }
        while(sprnSize < 0 || sprnSize == buffSize);// strlen(buff) >= buffSize-1
        GLOG_print(f, level, debug, buff);
        MEM_free(buff);
    }
    buff = NULL;
	fflush(f);
}

void GLOG_sprint( FILE* f, int level, logical debug, const char *format, ... )
{
    va_list arg_ptr;
    va_start(arg_ptr, format);
    GLOG_sprint_ex(f, level, debug, format, arg_ptr);
    va_end(arg_ptr);
}

void GLOG_sprintln( FILE* f, int level, logical debug, const char *format, ... )
{
    va_list arg_ptr;
    va_start(arg_ptr, format);
    GLOG_sprint_ex(f, level, debug, format, arg_ptr);
    GLOG_print(f, level, debug, "\n");
    va_end(arg_ptr);
}

void GLOG_ifail( int ifail, FILE *f, const char *fn, const char *fileName, int lineNo, logical isDebugLog )
{
    if (ifail != ITK_ok)
    {
        char buf[1024] = {0};
        char *err_string = NULL;

        int severityLevel = EMH_severity_error;
        char *severityString = NULL;
        int i = 0, n_ifails = 0, *severities = NULL, *ifails = NULL;
        char **texts = NULL;


        EMH_ask_errors(&n_ifails, (const int **)&severities, (const int **)&ifails, (const char ***)&texts);
        for(i=n_ifails-1; i>=0; i--)
        {
            if(ifails[i] == ifail)
            {
                err_string = (char*)MEM_alloc((int)strlen(texts[i])+1);
                strcpy(err_string, texts[i]);
                severityLevel = severities[i];
                break;
            }
        }

        // Ask value
        if(err_string == NULL)
        {
            EMH_ask_error_text(ifail, &err_string);
        }

        switch(severityLevel)
        {
        case EMH_severity_warning:
            {
                severityString = "WARNING";
            }
            break;
        case EMH_severity_information:
            {
                severityString = "INFORMATION";
            }
            break;
        default:
            {
                severityString = "ERROR";
            }
            break;
        }

        if( isDebugLog == true)
        {
            sprintf( buf, "[%s]: %d,%s.\nFn: %s F: %s Ln: %d\n",
                severityString,
                ifail,
                err_string,
                (fn == NULL ? "" : fn),
                (fileName == NULL ? "" : fileName),
                lineNo );
        }
        else
        {
            sprintf( buf, "[%s]:%s.\n",
                severityString,
                err_string);
        }

        if (f != NULL)
        {
            fprintf( f, buf );
        }
        if ( CONSOLE_PRINT )
        {
            if ( CONSOLE_SYS_PRINT )
                GTC_write_syslog( buf );
            printf( buf );
        }

        MEM_free (err_string);
    }
}


void LOG_SPRINT( int level, const char *format, ... )
{
    va_list arg_ptr;

    if (GLOG_instance.logFile == NULL)
        return;

    va_start(arg_ptr, format);
    GLOG_sprint_ex(GLOG_instance.logFile, level, GLOG_instance.debug, format, arg_ptr);
    va_end(arg_ptr);
}

void LOG_SPRINTLN( int level, const char *format, ... )
{
    va_list arg_ptr;

    if (GLOG_instance.logFile == NULL)
        return;

    va_start(arg_ptr, format);
    GLOG_sprint_ex(GLOG_instance.logFile, level, GLOG_instance.debug, format, arg_ptr);
    GLOG_print(GLOG_instance.logFile, level, GLOG_instance.debug, "\n");
    va_end(arg_ptr);
}
